﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Lime49;
using Lime49.UI;
using LockCrypt.Core;
using LockCrypt.Properties;
using Microsoft.Win32;

namespace LockCrypt {
    /// <summary>
    /// Dialog for importing and opening databases.
    /// </summary>
    public partial class WinImport : Window {
        //private OpenFileDialog dlgOpen;

        public static DependencyProperty FileTypeProperty = DependencyProperty.Register("FileType", typeof(Constants.DataType), typeof(WinImport), new PropertyMetadata(Constants.DataType.XML));
        /// <summary>
        /// Gets the type of file selected for import.
        /// </summary>
        /// <value>The type.</value>
        public Constants.DataType FileType {
            get { return (Constants.DataType)base.GetValue(FileTypeProperty); }
            set { base.SetValue(FileTypeProperty, value); }
        }

        public static DependencyProperty FileNameProperty = DependencyProperty.Register("FileName", typeof(string), typeof(WinImport), new PropertyMetadata(string.Empty));
        /// <summary>
        /// Gets the name of the selected file.
        /// </summary>
        /// <value>The name of the selected file.</value>
        public string FileName {
            get { return System.Convert.ToString(base.GetValue(FileNameProperty)); }
            set { base.SetValue(FileNameProperty, value); }
        }

        public static DependencyProperty EncryptionAlgorithmProperty = DependencyProperty.Register("EncryptionAlgorithm", typeof(EncryptionProviders), typeof(WinImport), new PropertyMetadata(EncryptionProviders.None));
        /// <summary>
        /// Gets the selected encryption algorithm.
        /// </summary>
        /// <value>The selected encryption algorithm.</value>
        public EncryptionProviders EncryptionAlgorithm {
            get { return (EncryptionProviders)base.GetValue(EncryptionAlgorithmProperty); }
            set { base.SetValue(EncryptionAlgorithmProperty, value); }
        }

        /// <summary>
        /// Initializes a new <see cref="WinImport"/>.
        /// </summary>
        public WinImport() {
            InitializeComponent();
            cboEncryption.ItemsSource = EnumBinder.EnumHelper.ToList<string>(typeof(EncryptionProviders));
            Dictionary<Constants.DataType, string> availableTypes = new Dictionary<Constants.DataType, string>() {
                { Constants.DataType.Auto, I18nUtils.GetString("Strings", "Auto")},
                { Constants.DataType.LegacyXML, I18nUtils.GetString("Strings", "LegacyXmlFile")},
                { Constants.DataType.Keepass2x, "Keepass 2.x XML File"},
            };
            lstType.ItemsSource = availableTypes;
            filenameChooser.FilterString = string.Format("{0}|*.*|{1} (*.xml)|*.xml",
                                       I18nUtils.GetString("Strings", "AllFiles"),
                                       I18nUtils.GetString("Strings", "XmlFiles"));
            filenameChooser.DefaultExtension = ".xml";
        }

        /// <summary>
        /// Initializes a new <see cref="WinImport"/>.
        /// </summary>
        /// <param name="type">The type to import.</param>
        /// <param name="encryption">The encryption algorithm.</param>
        public WinImport(Constants.DataType type, EncryptionProviders encryption) 
            :this() {
            FileType = type;
            EncryptionAlgorithm = encryption;
        }

        /// <summary>
        /// Closes the dialog if files have been selected.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void StartImport(object sender, ExecutedRoutedEventArgs e) {
            if(ValidateFilename()) {
                Settings.Default.Save();
                DialogResult = true;
            }
        }

        /// <summary>
        /// Closes the window.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.ExecutedRoutedEventArgs"/> instance containing the event data.</param>
        private void CloseWindow(object sender, ExecutedRoutedEventArgs e) {
            DialogResult = false;
        }

        /// <summary>
        /// Validates the filename entered.
        /// </summary>
        /// <returns><c>true</c> if the filename is valid, otherwise <c>false</c>.</returns>
        private bool ValidateFilename() {
            bool valid = true;
            if(string.IsNullOrEmpty(FileName)) {
                DialogBox.ShowAlert(this, I18nUtils.GetString("Errors", "FilenameRequired"), I18nUtils.GetString("Errors", "Error"));
                valid = false;
            } else {
                try {
                    FileInfo file = new FileInfo(FileName);
                    if(!file.Exists) {
                        DialogBox.ShowAlert(this, I18nUtils.GetString("Errors", "FileDoesNotExist"), I18nUtils.GetString("Errors", "FileNotFound"));
                        valid = false;
                    }
                } catch(Exception ex) {
                    DialogBox.ShowAlert(this, ex.Message, I18nUtils.GetString("Errors", "Error"));
                    valid = false;
                }
            }
            return valid;
        }

        /// <summary>
        /// Disables modification of the encryption algorithm depending on the selected file type.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Controls.SelectionChangedEventArgs"/> instance containing the event data.</param>
        private void lstType_SelectionChanged(object sender, SelectionChangedEventArgs e) {
            switch(FileType) {
                case Constants.DataType.LegacyXML:
                default:
                    EncryptionAlgorithm = EncryptionProviders.None;
                    cboEncryption.IsEnabled = false;
                    break;
            }
        }
    }
}
